/**
 * @author temujin Sep 6, 2011
 */
package paim.gh.view.paineis.arvore;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;

import paim.wingchun.app.Reflections;
import paim.wingchun.model.pojos.Pojo;

import paim.gh.model.pojos.*;

// TODO deveria sobreescrever classe wc
/**
 * @author temujin Sep 6, 2011
 */
public class ArvoreModel extends DefaultTreeModel {

    private static final long serialVersionUID = 1L;

    private Grade grade;

    private ArvoreNode nodeGrade;

    private ArvoreNode nodeProfessores;

    private ArvoreNode nodeAula;

    private ArvoreNode nodeBalde;

    private ArvoreNode nodeBalde$Curso;

    private ArvoreNode nodeBalde$DiaSemana;

    private ArvoreNode nodeBalde$Disciplina;

    private ArvoreNode nodeBalde$Doscente;

    private ArvoreNode nodeBalde$Horario;

    private ArvoreNode nodeBalde$Sala;

    private ArvoreNode nodeBalde$Semestre;

    private ArvoreNode nodeBalde$Turno;

    public ArvoreModel() {
        this(new DefaultMutableTreeNode("Nenhuma Grade"));
    }

    public ArvoreModel(Grade grade) {
        this(new ArvoreNode(Reflections.getRotuloS(Grade.class), grade));
        this.grade = grade;

        fillTree();
    }

    public ArvoreModel(TreeNode root, boolean asksAllowsChildren) {
        super(root, asksAllowsChildren);
    }

    public ArvoreModel(TreeNode root) {
        super(root);
    }

    public Grade getGrade() {
        return this.grade;
    }

    @Deprecated
    public void setGrade(Grade grade) {
        this.grade = grade;

    }

    private void fillTree() {

        nodeGrade = ((ArvoreNode) this.getRoot());

        nodeAula = new ArvoreNode(Aula.class);
        /* preenchendo com as aulas */
        nodeAula.addAll(getGrade().getAula());
        nodeGrade.add(nodeAula);

        nodeProfessores = new ArvoreNode(Professor.class);
        /* preenchendo com os professores */
        nodeProfessores.addAll(getGrade().getProfessor());
        nodeGrade.add(nodeProfessores);

        nodeBalde = new ArvoreNode(Balde.class);
        nodeGrade.add(nodeBalde);

        nodeBalde$Curso = new ArvoreNode(Curso.class);
        nodeBalde.add(nodeBalde$Curso);

        nodeBalde$DiaSemana = new ArvoreNode(Dia.class);
        nodeBalde.add(nodeBalde$DiaSemana);

        nodeBalde$Disciplina = new ArvoreNode(Disciplina.class);
        nodeBalde.add(nodeBalde$Disciplina);

        nodeBalde$Doscente = new ArvoreNode(Doscente.class);
        nodeBalde.add(nodeBalde$Doscente);

        nodeBalde$Horario = new ArvoreNode(Horario.class);
        nodeBalde.add(nodeBalde$Horario);

        nodeBalde$Sala = new ArvoreNode(Sala.class);
        nodeBalde.add(nodeBalde$Sala);

        nodeBalde$Semestre = new ArvoreNode(Semestre.class);
        nodeBalde.add(nodeBalde$Semestre);

        nodeBalde$Turno = new ArvoreNode(Turno.class);
        nodeBalde.add(nodeBalde$Turno);

        /* preenchendo o balde: balde eh tudo que esta disponivel para uso */
        Balde balde = getGrade().getBalde();
        if ( balde != null ) {
            ArvoreNode node;
            nodeBalde$Curso.addAll(balde.getCursos());
            nodeBalde$DiaSemana.addAll(balde.getDias());
            nodeBalde$Disciplina.addAll(balde.getDisciplinas());
            nodeBalde$Doscente.addAll(balde.getDoscentes());
            nodeBalde$Horario.addAll(balde.getHorarios());
            nodeBalde$Sala.addAll(balde.getSalas());
            nodeBalde$Semestre.addAll(balde.getSemestres());
            nodeBalde$Turno.addAll(balde.getTurnos());
        }

    }

    protected static TreeModel getDefaultTreeModel() {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Grade"); // TODO string e limpar o resto
        return new DefaultTreeModel(root);
    }

    public final ArvoreNode getNodeGrade() {
        return this.nodeGrade;
    }

    public final ArvoreNode getNodeProfessores() {
        return this.nodeProfessores;
    }

    public final ArvoreNode getNodeAula() {
        return this.nodeAula;
    }

    public final ArvoreNode getNodeBalde() {
        return this.nodeBalde;
    }

    /**
     * encontra o nodo correspondente a esse objeto
     *
     * @author paim 08/12/2011
     * @param pojo
     * @return ArvoreNode
     */
    public ArvoreNode findNode(Pojo pojo) {
        if ( pojo instanceof Aula ) {
            ArvoreNode nodo = (ArvoreNode) nodeAula.getFirstChild();
            do {
                if ( nodo.getObjeto().equals(pojo) )
                    return nodo;
                nodo = (ArvoreNode) nodo.getNextSibling();
            }
            while ( nodo != null );
        }
        else if ( pojo instanceof Professor ) {
            return null;
            //TODO
        }
        throw new IllegalArgumentException("pojo does not have a node.");
    }

    /**
     * @author temujin Dec 4, 2011
     * @return boolean
     */
    public boolean isBaldeChildren(ArvoreNode node) {
        if ( node.isNodeObjeto() ) {

        }
        else {
            // nodeBalde.
            // node.equals()
            return true;
        }

        return false;

    }

}
